import datetime
import os
import random
import time

from django.contrib.auth.decorators import login_required
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.db.models import Count, Q
from django.views.decorators.csrf import csrf_exempt

from content.models import CataLogModel, PostModel
from admin_manager.models import PassageWayModel, AdsModel, FriendLinkModel, OptionModel
from user.models import BBSUser, CommentModel, SignModel
from bbs.utils import get_pages_data


def posts_list(request, catalog_id=None):
    context = {}

    # 查询最近一周内的评论，计算出评论的帖子数量并排序
    hot_posts = CommentModel.objects.filter(
        create_at__gt=datetime.datetime.now() - datetime.timedelta(days=7))

    # 首页需要显示的内容
    if not catalog_id:
        context['passageways'] = PassageWayModel.objects.filter(enable=True).order_by('-priority', 'pk')
        context['ads'] = AdsModel.objects.filter(enable=True).order_by('-priority', 'pk')
        context['friend_links'] = FriendLinkModel.objects.filter(enable=True).order_by('-priority', 'pk')
        context['is_index'] = True
        context['users_info'] = BBSUser.objects.annotate(replies_num=Count('commentmodel')).filter(
            replies_num__gt=0).order_by('-replies_num')[:5]

        # 分解文章
        posts = PostModel.objects.all()
        context['top_list'] = posts.filter(is_top=True)
    else:
        catalog = get_object_or_404(CataLogModel, pk=catalog_id)
        context['is_index'] = False
        context['catalog_id'] = catalog_id
        context['title'] = catalog.name

        hot_posts = hot_posts.filter(post__catalog=catalog)
        posts = PostModel.objects.all().filter(catalog=catalog)

    hot_posts = hot_posts.values('post').annotate(Count('post')).order_by('-post__count').values_list('post')[:5]
    context['hot_posts'] = [PostModel.objects.get(pk=pk[0]) for pk in hot_posts]

    # 筛选
    filter_type = request.GET.get('type')
    sort_by = request.GET.get('sort')
    if filter_type == 'not_closed':
        posts = posts.filter(is_closed=False)
    elif filter_type == 'is_closed':
        posts = posts.filter(is_closed=True)
    elif filter_type == 'is_cream':
        posts = posts.filter(is_cream=True)
    if sort_by == 'hot':
        posts = posts.annotate(comments_num=Count('commentmodel')).order_by('-comments_num')

    # 分页
    try:
        size = int(request.GET.get('size', 10))
        page = int(request.GET.get('page', 1))
    except ValueError:
        return HttpResponse("参数不正确", status=400)
    posts, page_range = get_pages_data(posts, size, page)

    context['page_range'] = page_range
    context['posts'] = posts
    return render(request, 'post_list.html', context)


@login_required
@csrf_exempt
def sign(request):
    data = {'coin': 0, 'signed': True}
    user = request.user

    # 先获取是否已签到
    try:
        signed_data = SignModel.objects.get(user=user, sign_date=datetime.date.today())
    except SignModel.DoesNotExist:
        pass
    else:
        data['coin'] = signed_data.coin
        return JsonResponse({'data': data, 'status': 0})

    try:
        sign_interval = OptionModel.objects.get(code='sign_interval', enable=True).value.split('-')
    except OptionModel.DoesNotExist:
        return JsonResponse({'data': data, 'status': 0})
    else:
        coin = random.randint(int(sign_interval[0]), int(sign_interval[1]))
        data['coin'] = coin
    signed_data = SignModel(user=user, coin=data['coin'])
    signed_data.save()
    return JsonResponse({'data': data, 'status': 0})


@login_required
def sign_status(request):
    data = {'coin': 0, 'signed': False}
    user = request.user
    try:
        signed_data = SignModel.objects.get(user=user, sign_date=datetime.date.today())
    except SignModel.DoesNotExist:
        pass
    else:
        data['coin'] = signed_data.coin
        data['signed'] = True

    return JsonResponse({'data': data, 'status': 0})


@login_required
def update_avatar(request):
    upload_file = request.FILES.get('image')
    if not upload_file:
        return JsonResponse({'status': 7, 'msg': '获取不到上传的图片，请重新上传'})

    user = request.user
    user.avatar = upload_file
    user.save()

    return JsonResponse({'status': 0, 'msg': '上传成功'})


@login_required
@csrf_exempt
def upload_file(request):
    smfile = request.FILES['smfile']
    filename = str(time.time()).replace('.', '') + '.' + smfile.name.split('.')[-1]

    fs = FileSystemStorage()
    filename = fs.save(os.path.join('uploads', filename), smfile)
    uploaded_file_url = fs.url(filename)
    return JsonResponse({'status': 0, 'data': {'url': uploaded_file_url}})


def search(request):
    kw = request.GET.get('kw', '')
    page = int(request.GET.get('page', 1))
    if not kw:
        return render(request, "search.html", {'message': '请输入关键字', 'kw': kw})

    posts = PostModel.objects.filter(Q(title__icontains=kw) | Q(content__icontains=kw))
    page_data, page_range = get_pages_data(posts, 10, page)
    return render(request, "search.html", {
        'kw': kw,
        'page_data': page_data,
        'page_range': page_range,
        'total': posts.count()
    })
